package rollercoaster.railway;

import java.util.HashMap;
import java.util.Map;

import javax.media.opengl.GL2ES2;
import javax.media.opengl.GLES2;

import rollercoaster.commons.Material;
import rollercoaster.commons.Model;
import rollercoaster.commons.Node;
import rollercoaster.commons.Vertex3D;
import rollercoaster.commons.interfaces.ITrajectory;
import rollercoaster.commons.interfaces.IVertexReader;
import rollercoaster.commons.interfaces.NodoProducer;
import rollercoaster.commons.interfaces.SurfaceTessellationAlgorithm;
import rollercoaster.environment.interfaces.IModelReader;
import rollercoaster.environment.utils.ModelMaker;
import rollercoaster.railway.interfaces.BinarioDataReader;
import rollercoaster.railway.utils.BinarioParameterContainer;

public abstract class RailProducer implements NodoProducer {

	protected SurfaceTessellationAlgorithm tess;
	protected BinarioDataReader binarioReader;
	protected IVertexReader vertexReader;
	
	protected Vertex3D distanceBetweenRails;


	public RailProducer(SurfaceTessellationAlgorithm tess,
			BinarioDataReader binarioReader, IVertexReader vertexReader) {
		super();
		this.tess = tess;
		this.binarioReader = binarioReader;
		this.vertexReader = vertexReader;
	}

	protected BinarioParameterContainer initRailParameters(GL2ES2 gl) {
		
		ITrajectory tr=getRailTrajectory();
		HashMap<String, HashMap<String, String>> textures=binarioReader.getTextureInfo();
		HashMap<String,Material> materialMap=new HashMap<String, Material>();
		for (Map.Entry<String, HashMap<String, String>> entry : textures.entrySet()) {
			Material mat=new Material(entry.getValue().get("texture-file"));
			mat.init(gl);
			float[] texMatrix={Float.parseFloat(entry.getValue().get("txa")),Float.parseFloat(entry.getValue().get("txb")),
								Float.parseFloat(entry.getValue().get("txc")),Float.parseFloat(entry.getValue().get("txd"))};
			mat.setTransformMatrix(texMatrix);
			materialMap.put(entry.getKey(), mat);
		}
		
		HashMap<String, String> middleMap=binarioReader.getTubeParameters("middle");
		HashMap<String, String> lateralMap=binarioReader.getTubeParameters("lateral");
		HashMap<String, String> littleMap=binarioReader.getTubeParameters("little");
		HashMap<String, String> supportMap=binarioReader.getTubeParameters("support");
		
		BinarioParameterContainer bpc=new BinarioParameterContainer();
		bpc.setTr(tr);
		bpc.setMiddlemap(middleMap);
		bpc.setLateralmap(lateralMap);
		bpc.setLittlemap(littleMap);
		bpc.setSupportmap(supportMap);
		bpc.setMaterialmap(materialMap);
		return bpc;
	}

	protected Model produceModel(GL2ES2 gl, HashMap<String, Material> materialMap, HashMap<String, String> map,
			Tube surface) {
						IModelReader mr=tess.tessellate(surface);
						ModelMaker maker=new ModelMaker(mr);	
						Model modelMiddle=maker.makeModel();
						modelMiddle.initBuffers(gl);
						modelMiddle.setMaterial(materialMap.get(map.get("texture-name")));
						return modelMiddle;
			}
	
	public ITrajectory getRailTrajectory(){
		HashMap<String, String> trajMap=binarioReader.getTrajectoryInfo();
		String pathBase=trajMap.get("base-trajectory");
		String pathUp=trajMap.get("up-trajectory");
		UniformSecondOrderClosedBSpline base=new UniformSecondOrderClosedBSpline(vertexReader.getVertices(pathBase));
		UniformSecondOrderClosedBSpline up=new UniformSecondOrderClosedBSpline(vertexReader.getVertices(pathUp));
		Trajectory tr=new Trajectory(base, up);
		return tr;
	}
	
	public Vertex3D getDistanceBetweenTubes(){
		return distanceBetweenRails;
	}

}